home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4.md / devSmem.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  11KB  |  361 lines

  1. /* 
  2.  * devSmem.c --
  3.  *
  4.  *    Stubs to implement /dev/smem.  Allow reading and writing
  5.  *      to kernel memory.
  6.  *
  7.  *
  8.  * Copyright 1987 Regents of the University of California
  9.  * All rights reserved.
  10.  */
  11.  
  12. #ifndef lint
  13. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4.md/devSmem.c,v 9.1 92/08/13 15:53:51 secor Exp $ SPRITE (Berkeley)";
  14. #endif not lint
  15.  
  16. #include "sprite.h"
  17. #include "fs.h"
  18. #include <vmSunConst.h>
  19. #include <dbg.h>
  20. #define NOGAP
  21.  
  22. extern int vm_PageSize;
  23. extern int mach_KernStackSize;
  24. extern int vmBlockCacheEndAddr;
  25. extern int vmBlockCacheBaseAddr;
  26. extern int vmStackEndAddr;
  27. extern int vmStackBaseAddr;
  28. extern int vmMemEnd;
  29. extern Address mach_KernStart;
  30. extern Address mach_CodeStart;
  31. extern int end;
  32.  
  33.  
  34. /*
  35.  *----------------------------------------------------------------------
  36.  *
  37.  *  Dev_SmemRead --
  38.  *
  39.  *    Return number of bytes read and SUCCESS if nonzero bytes returned.
  40.  *
  41.  * Results:
  42.  *    A standard Sprite return status.
  43.  *
  44.  * Side effects:
  45.  *    None.
  46.  *
  47.  *----------------------------------------------------------------------
  48.  */
  49. /*ARGSUSED*/
  50. ReturnStatus
  51. Dev_SmemRead(devicePtr, readPtr, replyPtr)
  52.     Fs_Device *devicePtr;
  53.     Fs_IOParam    *readPtr;    /* Read parameter block */
  54.     Fs_IOReply    *replyPtr;    /* Return length and signal */ 
  55. {
  56.   int bytesLeft;
  57.   int kernelAddress;
  58.   int numPages, bytesInPage;
  59.   char *bufPtr;
  60.   StopInfo stopInfo;
  61.   Dbg_DumpBounds currentBounds;
  62.   
  63.   stopInfo.codeStart = (int)mach_CodeStart;
  64.   stopInfo.trapType = 0;
  65. /*  stopInfo.regs = ;*/
  66.   currentBounds.pageSize = vm_PageSize;
  67.   currentBounds.stackSize = mach_KernStackSize;
  68.   currentBounds.kernelCodeStart = (unsigned int) mach_KernStart;
  69.   currentBounds.kernelCodeSize  =
  70.     (unsigned int) (((Address)(&end)) - mach_KernStart);
  71.   currentBounds.kernelDataStart  = ((unsigned int)(&end));
  72.   currentBounds.kernelDataSize   = (unsigned int)
  73.     (((Address)(vmMemEnd)) - ((Address)(&end)));
  74.   currentBounds.kernelStacksStart = (unsigned int)vmStackBaseAddr;
  75.   currentBounds.kernelStacksSize = (unsigned int)
  76.     (vmStackEndAddr - vmStackBaseAddr);
  77.   currentBounds.fileCacheStart   = (unsigned int)vmBlockCacheBaseAddr;
  78.   currentBounds.fileCacheSize    = (unsigned int) (vmBlockCacheEndAddr -
  79.                         vmBlockCacheBaseAddr);
  80.   kernelAddress = readPtr->offset;
  81.   bytesLeft = readPtr->length;
  82.   bufPtr = readPtr->buffer;
  83.   if (kernelAddress < sizeof(StopInfo)) {
  84.     if (bytesLeft + kernelAddress <= sizeof(StopInfo)) {
  85.       bcopy(((char *)&stopInfo) + kernelAddress, readPtr->buffer, readPtr->length);
  86.       replyPtr->length = readPtr->length;
  87.       return(SUCCESS);
  88.     }
  89.     bcopy(((char *)&stopInfo) + kernelAddress, readPtr->buffer, sizeof(StopInfo) - kernelAddress);
  90.     bytesLeft -= sizeof(StopInfo) - kernelAddress;
  91.     bufPtr += sizeof(StopInfo) - kernelAddress;
  92.     kernelAddress = sizeof(StopInfo);
  93.   }
  94.   if (kernelAddress < (sizeof(StopInfo) + sizeof(Dbg_DumpBounds))) {
  95.     if (bytesLeft + kernelAddress <= sizeof(StopInfo) + sizeof(Dbg_DumpBounds)) {
  96.       bcopy(((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, bufPtr, bytesLeft);
  97.       replyPtr->length = readPtr->length;
  98.       return(SUCCESS);
  99.     }
  100.     bcopy(((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, bufPtr, sizeof(Dbg_DumpBounds));
  101.     bytesLeft -= sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  102.     bufPtr += sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  103.     kernelAddress = mach_KernStart;
  104.   }
  105.   kernelAddress += mach_KernStart - (sizeof(StopInfo) + sizeof(Dbg_DumpBounds));
  106.  
  107. #ifdef NOGAP
  108.   if (kernelAddress > vmMemEnd) {
  109.     kernelAddress += vmStackBaseAddr - vmMemEnd;
  110.   }
  111.   if (kernelAddress > vmStackEndAddr) {
  112.     kernelAddress += vmBlockCacheBaseAddr - vmStackEndAddr;
  113.   }
  114.   if (kernelAddress > vmBlockCacheEndAddr) {
  115.     return (SYS_INVALID_ARG);
  116.   }
  117. #else
  118.   if (kernelAddress > vmMemEnd &&
  119.       kernelAddress < vmStackBaseAddr) {
  120.     return(SYS_INVALID_ARG);
  121.   }
  122.   if (kernelAddress > vmStackEndAddr &&
  123.       kernelAddress < vmBlockCacheBaseAddr) {
  124.     return(SYS_INVALID_ARG);
  125.   }
  126.   if (kernelAddress > vmBlockCacheEndAddr) {
  127.     return(SYS_INVALID_ARG);
  128.   }
  129. #endif
  130.  
  131.   numPages = ((kernelAddress + bytesLeft - 1) >> VMMACH_PAGE_SHIFT) - 
  132.     (kernelAddress >> VMMACH_PAGE_SHIFT);
  133.   if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  134.     replyPtr->length = 0;
  135.     return(SYS_ARG_NOACCESS);
  136.   }
  137.   bytesInPage = vm_PageSize - (kernelAddress & (vm_PageSize-1));
  138.   if (bytesLeft < bytesInPage) {
  139.     bcopy(kernelAddress, bufPtr, bytesLeft);
  140.     replyPtr->length = readPtr->length;
  141.     return(SUCCESS);
  142.   }
  143.   bcopy(kernelAddress, bufPtr, bytesInPage);
  144.   bytesLeft -= bytesInPage;
  145.   bufPtr += vm_PageSize;
  146.   while (numPages > 0) {
  147.     if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  148.       replyPtr->length = 0;
  149.       return(SYS_ARG_NOACCESS);
  150.     }
  151.     if (bytesLeft < vm_PageSize) {
  152.       bcopy(kernelAddress, bufPtr, bytesLeft);
  153.       replyPtr->length = readPtr->length;
  154.       return(SUCCESS);
  155.     }
  156.     bcopy(kernelAddress, bufPtr, vm_PageSize);
  157.     bytesLeft -= vm_PageSize;
  158.     bufPtr += vm_PageSize;
  159.     numPages--;
  160.   }
  161.   replyPtr->length = readPtr->length;
  162.   return(SUCCESS);
  163. }
  164.  
  165.  
  166. /*
  167.  *----------------------------------------------------------------------
  168.  *
  169.  *  Dev_SmemWrite --
  170.  *
  171.  *    Writes if it can, and returns SUCCESS if it wrote.
  172.  *
  173.  * Results:
  174.  *    A standard Sprite return status.
  175.  *
  176.  * Side effects:
  177.  *    None.
  178.  *
  179.  *----------------------------------------------------------------------
  180.  */
  181. /*ARGSUSED*/
  182. ReturnStatus
  183. Dev_SmemWrite(devicePtr, writePtr, replyPtr)
  184.     Fs_Device *devicePtr;
  185.     Fs_IOParam    *writePtr;    /* Write parameter block */
  186.     Fs_IOReply    *replyPtr;    /* Return length and signal */ 
  187. {
  188.   int bytesLeft;
  189.   int kernelAddress;
  190.   int numPages, bytesInPage;
  191.   char *bufPtr;
  192.   StopInfo stopInfo;
  193.   Dbg_DumpBounds currentBounds;
  194.   
  195.   stopInfo.codeStart = (int)mach_CodeStart;
  196.   stopInfo.trapType = 0;
  197. /*  stopInfo.regs = ;*/
  198.   currentBounds.pageSize = vm_PageSize;
  199.   currentBounds.stackSize = mach_KernStackSize;
  200.   currentBounds.kernelCodeStart = (unsigned int) mach_KernStart;
  201.   currentBounds.kernelCodeSize  =
  202.     (unsigned int) (((Address)(&end)) - mach_KernStart);
  203.   currentBounds.kernelDataStart  = ((unsigned int)(&end));
  204.   currentBounds.kernelDataSize   = (unsigned int)
  205.     (((Address)(vmMemEnd)) - ((Address)(&end)));
  206.   currentBounds.kernelStacksStart = (unsigned int)vmStackBaseAddr;
  207.   currentBounds.kernelStacksSize = (unsigned int)
  208.     (vmStackEndAddr - vmStackBaseAddr);
  209.   currentBounds.fileCacheStart   = (unsigned int)vmBlockCacheBaseAddr;
  210.   currentBounds.fileCacheSize    = (unsigned int) (vmBlockCacheEndAddr -
  211.                         vmBlockCacheBaseAddr);
  212.   kernelAddress = writePtr->offset;
  213.   bytesLeft = writePtr->length;
  214.   bufPtr = writePtr->buffer;
  215.   if (kernelAddress < sizeof(StopInfo)) {
  216.     if (bytesLeft + kernelAddress <= sizeof(StopInfo)) {
  217.       bcopy(writePtr->buffer, ((char *)&stopInfo) + kernelAddress, writePtr->length);
  218.       replyPtr->length = writePtr->length;
  219.       return(SUCCESS);
  220.     }
  221.     bcopy(writePtr->buffer, ((char *)&stopInfo) + kernelAddress, sizeof(StopInfo) - kernelAddress);
  222.     bytesLeft -= sizeof(StopInfo) - kernelAddress;
  223.     bufPtr += sizeof(StopInfo) - kernelAddress;
  224.     kernelAddress = sizeof(StopInfo);
  225.   }
  226.   if (kernelAddress < (sizeof(StopInfo) + sizeof(Dbg_DumpBounds))) {
  227.     if (bytesLeft + kernelAddress <= sizeof(StopInfo) + sizeof(Dbg_DumpBounds)) {
  228.       bcopy(bufPtr, ((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, bytesLeft);
  229.       replyPtr->length = writePtr->length;
  230.       return(SUCCESS);
  231.     }
  232.     bcopy(bufPtr, ((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, sizeof(Dbg_DumpBounds));
  233.     bytesLeft -= sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  234.     bufPtr += sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  235.     kernelAddress = mach_KernStart;
  236.   }
  237.   kernelAddress += mach_KernStart - (sizeof(StopInfo) + sizeof(Dbg_DumpBounds));
  238.  
  239. #ifdef NOGAP
  240.   if (kernelAddress > vmMemEnd) {
  241.     kernelAddress += vmStackBaseAddr - vmMemEnd;
  242.   }
  243.   if (kernelAddress > vmStackEndAddr) {
  244.     kernelAddress += vmBlockCacheBaseAddr - vmStackEndAddr;
  245.   }
  246.   if (kernelAddress > vmBlockCacheEndAddr) {
  247.     return (SYS_INVALID_ARG);
  248.   }
  249. #else
  250.   if (kernelAddress > vmMemEnd &&
  251.       kernelAddress < vmStackBaseAddr) {
  252.     return(SYS_INVALID_ARG);
  253.   }
  254.   if (kernelAddress > vmStackEndAddr &&
  255.       kernelAddress < vmBlockCacheBaseAddr) {
  256.     return(SYS_INVALID_ARG);
  257.   }
  258.   if (kernelAddress > vmBlockCacheEndAddr) {
  259.     return(SYS_INVALID_ARG);
  260.   }
  261. #endif
  262.  
  263.   numPages = ((kernelAddress + bytesLeft - 1) >> VMMACH_PAGE_SHIFT) - 
  264.     (kernelAddress >> VMMACH_PAGE_SHIFT);
  265.   if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  266.     replyPtr->length = 0;
  267.     return(SYS_ARG_NOACCESS);
  268.   }
  269.   bytesInPage = vm_PageSize - (kernelAddress & (vm_PageSize-1));
  270.   if (bytesLeft < bytesInPage) {
  271.     bcopy(bufPtr, kernelAddress, bytesLeft);
  272.     replyPtr->length = writePtr->length;
  273.     return(SUCCESS);
  274.   }
  275.   bcopy(bufPtr, kernelAddress, bytesInPage);
  276.   bytesLeft -= bytesInPage;
  277.   bufPtr += vm_PageSize;
  278.   while (numPages > 0) {
  279.     if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  280.       replyPtr->length = 0;
  281.       return(SYS_ARG_NOACCESS);
  282.     }
  283.     if (bytesLeft < vm_PageSize) {
  284.       bcopy(bufPtr, kernelAddress, bytesLeft);
  285.       replyPtr->length = writePtr->length;
  286.       return(SUCCESS);
  287.     }
  288.     bcopy(bufPtr, kernelAddress, vm_PageSize);
  289.     bytesLeft -= vm_PageSize;
  290.     bufPtr += vm_PageSize;
  291.     numPages--;
  292.   }
  293.   replyPtr->length = writePtr->length;
  294.   return(SUCCESS);
  295. }
  296.  
  297.  
  298. /*
  299.  *----------------------------------------------------------------------
  300.  *
  301.  * Dev_SmemIOControl --
  302.  *
  303.  *    This procedure handles IOControls for /dev/smem and other
  304.  *    devices.  It refuses all IOControls except for a few of
  305.  *    the generic ones, for which it does nothing.
  306.  *
  307.  * Results:
  308.  *    A standard Sprite return status.
  309.  *
  310.  * Side effects:
  311.  *    None.
  312.  *
  313.  *----------------------------------------------------------------------
  314.  */
  315.  
  316. /* ARGSUSED */
  317. ReturnStatus
  318. Dev_SmemIOControl(devicePtr, ioctlPtr, replyPtr)
  319.     Fs_Device            *devicePtr;
  320.     Fs_IOCParam        *ioctlPtr;
  321.     Fs_IOReply        *replyPtr;
  322. {
  323.     if ((ioctlPtr->command == IOC_GET_FLAGS)
  324.     || (ioctlPtr->command == IOC_SET_FLAGS)
  325.     || (ioctlPtr->command == IOC_SET_BITS)
  326.     || (ioctlPtr->command == IOC_CLEAR_BITS)
  327.     || (ioctlPtr->command == IOC_REPOSITION)) {
  328.     return SUCCESS;
  329.     }
  330.     return GEN_NOT_IMPLEMENTED;
  331. }
  332.  
  333. /*
  334.  *----------------------------------------------------------------------
  335.  *
  336.  * Dev_SmemSelect --
  337.  *
  338.  *    This procedure handles selects for /dev/smem and other
  339.  *    devices that are always ready.
  340.  *
  341.  * Results:
  342.  *    The device is indicated to be readable and writable.
  343.  *
  344.  * Side effects:
  345.  *    None.
  346.  *
  347.  *----------------------------------------------------------------------
  348.  */
  349.  
  350. /* ARGSUSED */
  351. ReturnStatus
  352. Dev_SmemSelect(devicePtr, readPtr, writePtr, exceptPtr)
  353.     Fs_Device    *devicePtr;    /* Ignored. */
  354.     int    *readPtr;        /* Read bit to clear if not readable */
  355.     int    *writePtr;        /* Write bit to clear if not readable */
  356.     int    *exceptPtr;        /* Except bit to clear if not readable */
  357. {
  358.     *exceptPtr = 0;
  359.     return(SUCCESS);
  360. }
  361.